package com.example.kotlin.ui;

import android.Manifest;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.example.kotlin.BuildConfig;
import com.example.kotlin.R;
import com.example.kotlin.aspect.CheckNet;
import com.example.kotlin.design.pattern.WrapRecyclerView;
import com.example.kotlin.design.pattern.proxy.ConnectorManagerProxy;
import com.example.kotlin.download.DownloadActivity;
import com.example.kotlin.service.IMyAidlInterface;
import com.example.kotlin.service.MyService;
import com.example.kotlin.utils.OnClick;
import com.example.kotlin.utils.ViewUtil;
import com.example.kotlin.utils.ViewUtils;
import com.example.myknife.ButterKnife;
import com.example.myknife.Unbinder;
import com.example.myknife_annotations.BindView;
import com.tbruyelle.rxpermissions2.RxPermissions;

import java.io.File;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

/**
 * @author chenmengjia
 */
public class HomeActivity extends AppCompatActivity {
    @BindView(value = R.id.btn)
    Button btn;
    @BindView(value = R.id.btn_network)
    Button btn_network;
    private Unbinder mUnbinder;
    private ServiceConnection mConnection;
    public static final String TAG = HomeActivity.class.getName();
    @BindView(R.id.rv)
    public WrapRecyclerView mRecyclerView;
    private List<Integer> mItems = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        ViewUtils.inject(this);
        mUnbinder = ButterKnife.bind(this);
        btn.setText("跳转MainActivity".toLowerCase());






//        ProxyListener proxyListener = new ProxyListener();
//        View.OnClickListener listener = (View.OnClickListener) Proxy.newProxyInstance(View.OnClickListener.class.getClassLoader(), new Class[]{View.OnClickListener.class}, new InvocationHandler() {
//            @Override
//            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//
//                // Object invoke = method.invoke(proxyListener, args);
//                boolean networkAvailable = ViewUtil.INSTANCE.isNetworkAvailable(HomeActivity.this);
//                if (networkAvailable){
//                    method.invoke(proxyListener, args);
//                }else {
//
//                    Toast.makeText(HomeActivity.this,"没有网络",Toast.LENGTH_SHORT).show();
//                }
//
//                return null;
//            }
//        });
//
//
//        btn_network.setOnClickListener(listener);
        //    setCheckNetOnClickListener(btn_network, v -> checkNetwork());

        initRecyclyer();

// 有三个类需要用户去关注，后面我们有可能会自己去更新代码，用户就需要换调用方式
        // 调用的方式 门面

//        DownloadFacade.getFacade().init(this);
//
//        DownloadFacade.getFacade()
//                .startDownload("http://acj3.pc6.com/pc6_soure/2017-11/com.ss.android.essay.joke_664.apk", new DownloadCallback() {
//                    @Override
//                    public void onFailure(IOException e) {
//                        e.printStackTrace();
//                    }
//
//                    @Override
//                    public void onSucceed(File file) {
//                        installFile(file);
//                    }
//                });


        // 多线断点下载，只要客户端做一下处理就可以了
        // 什么叫做断点续传，逻辑是什么？
        // 如果下载中断（网络断开，程序退出），下次可以接着上次的地方下载
        // 多线程的逻辑是什么？多个线程读后台文件每个线程只负责读取单独的内容

        // 文件更新 ，专门下载apk软件（应用宝，迅雷，百度云）

        // 文件更新，1. 可以直接跳转到浏览器更新，2.直接下载不断点，也不多线程（OkHttp）3.多线程 4. 多线程加断点

        // 专门下载apk软件：多线程 + 断点，最多只能同时下载几个文件，一些正在下载，一些暂停，一些准备，参考 OKHttp 源码 Dispatch 的逻辑

        // 4. 多线程加断点
        /*OkHttpManager okHttpManager = new OkHttpManager();
        Call call = okHttpManager.asyncCall("http://acj3.pc6.com/pc6_soure/2017-11/com.ss.android.essay.joke_664.apk");

        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                // 不断的读写文件，单线程
                InputStream inputStream = response.body().byteStream();

                File file = new File(getCacheDir(),"x02345.apk");

                OutputStream outputStream = new FileOutputStream(file);

                int len = 0;
                byte[] buffer = new byte[1024*10];

                while ((len = inputStream.read(buffer))!=-1){
                    outputStream.write(buffer,0,len);
                }

                inputStream.close();
                outputStream.close();

                installFile(file);
            }
        });*/

        // 断点续传，需要服务器配合，思路跟断点下载类似
    }

    private void installFile(File file) {

        // 核心是下面几句代码
        Intent intent = new Intent(Intent.ACTION_VIEW);
        //判断是否是AndroidN以及更高的版本
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            Uri contentUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".fileProvider", file);
            intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
        } else {
            intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }
        startActivity(intent);
    }


    private void initRecyclyer() {
        for (int i = 0; i < 100; i++) {
            mItems.add(i);
        }
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        // 采用装饰设计模式，让其支持添加头部和底部
        /*RecyclerAdapter mRealAdapter = new RecyclerAdapter();
        WrapRecyclerAdapter wrapRecyclerAdapter = new WrapRecyclerAdapter(mRealAdapter);
        // setAdapter
        mRecyclerView.setAdapter(wrapRecyclerAdapter);*/
        mRecyclerView.setAdapter(new RecyclerAdapter());
        // 添加头部 有没有问题？
        View headerView = LayoutInflater.from(this).inflate(R.layout.layout_header_view, mRecyclerView, false);
        mRecyclerView.addHeaderView(headerView);
//        View footerView = LayoutInflater.from(this).inflate(R.layout.layout_header_view, mRecyclerView, false);
        mRecyclerView.addFooterView(headerView);
        // 面向对象的六大基本原则在哪里？最少知识原则又在哪里呢？必须要像ListView让其支持
        // 不要把代码过度封装，在我看来，业务逻辑能分开就分开，底层和中间层不含业务逻辑的能封装就封装不用纠结过度封装
    }

    protected void setCheckNetOnClickListener(View view, View.OnClickListener realListener) {
        View.OnClickListener listenerProxy = (View.OnClickListener) Proxy.newProxyInstance(View.OnClickListener.class.getClassLoader(), new Class[]{View.OnClickListener.class}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //判断网络的切面
                boolean networkAvailable = ViewUtil.INSTANCE.isNetworkAvailable(HomeActivity.this);
                if (networkAvailable) {
                    method.invoke(realListener, args);
                } else {

                    Toast.makeText(HomeActivity.this, "没有网络", Toast.LENGTH_SHORT).show();
                }

                return null;
            }
        });
        view.setOnClickListener(listenerProxy);

    }

    class ProxyListener implements View.OnClickListener {

        @Override
        public void onClick(View v) {
            checkNetwork();
        }


    }

    @OnClick(R.id.btn_db)
    void runDatabase() {
        Intent intent = new Intent(HomeActivity.this, GreendaoActivity.class);
        startActivity(intent);
    }

    @OnClick(R.id.btn_network)
    @CheckNet
    void checkNetwork() {
//        TestDialog testDialog = new TestDialog();
//        testDialog.show(getSupportFragmentManager(),"ww");
        RxPermissions rxPermissions = new RxPermissions(this);
        rxPermissions.request(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                .subscribe(isGranted -> {
                    //动态获取权限后，调用预览Activity
                    if (isGranted) {
                        ConnectorManagerProxy.getProxy().reloadOperationListPost("1234");
                        Intent intent = new Intent(HomeActivity.this, MainActivity.class);
                        startActivity(intent);
                    }
                });


    }

    public void runStart(View view) {
        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
    }

    public void runService(View view) {
        if (mConnection == null) {
            mConnection = new ServiceConnection() {

                //bind服务，onCreate之后
                @Override
                public void onServiceConnected(ComponentName name, IBinder binder2) {


                    Log.e(TAG, "onServiceConnected");
                    binder = IMyAidlInterface.Stub.asInterface(binder2);
                }

                //unBind服务时，在onDestroy之前
                @Override
                public void onServiceDisconnected(ComponentName name) {
                    Log.e(TAG, "onServiceDisconnected");
                }
            };
        }


        Intent intent = new Intent(this, MyService.class);
        //startService(intent);
        bindService(intent, mConnection, BIND_AUTO_CREATE);
    }

    public void stopService(View view) {
        if (mConnection == null) return;
        Intent intent = new Intent(this, MyService.class);
        //  stopService(intent)
        unbindService(mConnection);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mUnbinder.unbind();
        unbindService(mConnection);
        mConnection = null;
    }

    private IMyAidlInterface binder = null;

    public void download(View view) {
        Intent intent = new Intent(this, DownloadActivity.class);
        startActivity(intent);
    }

    public void runGlide(View view) {
        Intent intent = new Intent(this, GlideActivity.class);
        startActivity(intent);
    }

    private class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_rv, parent, false);
            return new ViewHolder(itemView);
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, final int position) {
            holder.text.setText("position = " + mItems.get(position));
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mItems.remove(position);
                    notifyDataSetChanged();
                }
            });
        }

        @Override
        public int getItemCount() {
            return mItems.size();
        }

        class ViewHolder extends RecyclerView.ViewHolder {
            public TextView text;

            public ViewHolder(View itemView) {
                super(itemView);
                text = (TextView) itemView.findViewById(R.id.text);
            }
        }
    }
}
